package com.carleasoft.mps.cms.business.user.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.carleasoft.mps.cms.business.article.constants.ExceptionCMSEnum;
import com.carleasoft.mps.cms.business.process.bean.vo.UserInfoVos;
import com.carleasoft.mps.cms.business.process.dao.BaseProcessNodeRelMapper;
import com.carleasoft.mps.cms.business.process.service.BaseProcessNodeRelService;
import com.carleasoft.mps.cms.business.user.bean.UserSkill;
import com.carleasoft.mps.cms.business.user.bean.UserSkillType;
import com.carleasoft.mps.cms.business.user.bean.po.UserSkillPo;
import com.carleasoft.mps.cms.business.user.bean.vo.*;
import com.carleasoft.mps.cms.business.user.dao.UserSkillMapper;
import com.carleasoft.mps.cms.business.user.service.UserSkillService;
import com.carleasoft.mps.cms.business.user.service.UserSkillTypeService;
import com.carleasoft.mps.cms.business.write.bean.vo.UserListVos;
import com.carleasoft.mps.core.exceptions.BusinessException;
import com.carleasoft.mps.core.user.ThreadUserContext;
import com.carleasoft.mps.core.user.UserCacheData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zang
 * @since 2023-05-25
 */
@Service
public class UserSkillServiceImpl extends ServiceImpl<UserSkillMapper, UserSkill> implements UserSkillService {
    @Autowired
    private UserSkillTypeService userSkillTypeService;
    @Autowired
    private BaseProcessNodeRelMapper baseProcessNodeRelMapper;

    @Override
    public Page<UserSkill> pageUserSkill(Page page, UserSkillPo userSkillPo) {
        Page<UserSkill> res = this.getBaseMapper().pageUserSkill(page, userSkillPo);

        if (CollUtil.isNotEmpty(res.getRecords())) {

            Map<Integer, List<UserSkill>> map = res.getRecords().stream().collect(Collectors.groupingBy(UserSkill::getUserType));
            if (map.containsKey(5)) {
                List<UserSkill> userSkills = map.get(5);
                List<Long> ids = userSkills.stream().map(UserSkill::getId).collect(Collectors.toList());
                List<UserSkill> skills = this.listByIds(ids);
                Map<Long, UserSkill> skillMap = skills.stream().collect(Collectors.toMap(UserSkill::getId, Function.identity()));
                for (UserSkill record : res.getRecords()) {
                    if (skillMap.containsKey(record.getId())) {
                        record.setHeadPicture(skillMap.get(record.getId()).getHeadPicture());
                    }
                }
            } else {
                Set<String> userCodes = res.getRecords().stream().map(UserSkill::getUserCode).collect(Collectors.toSet());
                List<UserInfoVos> userInfoVos = baseProcessNodeRelMapper.userCodes(userCodes);
                Map<String, List<UserInfoVos>> listMap = new HashMap<>();
                if (CollUtil.isNotEmpty(userInfoVos)) {
                    listMap = userInfoVos.stream().collect(Collectors.groupingBy(UserInfoVos::getUserCode));
                }
                for (UserSkill record : res.getRecords()) {
                    if (listMap.containsKey(record.getUserCode())) {
                        StringBuilder deptName = new StringBuilder();
                        List<UserInfoVos> infoVos = listMap.get(record.getUserCode());
                        for (int i1 = 0; i1 < infoVos.size(); i1++) {
                            UserInfoVos infoVos1 = infoVos.get(i1);
                            if (i1 == infoVos.size() - 1) {
                                deptName.append(infoVos1.getDeptName());
                            } else {
                                deptName.append(infoVos1.getDeptName()).append("、");
                            }

                        }
                        record.setDeptName(deptName.toString());
                    }
                }
            }

        }
        return res;
    }

    @Override
    public List<UserSkill> getUserSkillTypeList(UserSkill userSkill) {
        return this.baseMapper.getUserSkillTypeList(userSkill);
    }

    @Override
    public Boolean saveUserSkill(UserSkill userSkill) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        // 判断是否有该人才
        if (userSkill.getUserType() != 5) {
            List<UserSkill> list = new ArrayList<>();
            for(int j = 0;j<userSkill.getUserCodeList().size();j++){
                list = this.list(new QueryWrapper<UserSkill>()
                        .eq("USER_CODE", userSkill.getUserCodeList().get(j))
                        .eq("USER_TYPE", userSkill.getUserType())
                        .eq("IS_DELETE", 0)
                );
                if (list.size() > 0) {
                    return false;
                }
            }
        } else {
            List<UserSkill> list = this.list(Wrappers.<UserSkill>lambdaQuery()
                    .eq(UserSkill::getUserType, 5)
                    .eq(UserSkill::getDeptCode, userSkill.getDeptCode()));
            if (list.size() > 0) {
                throw new BusinessException(ExceptionCMSEnum.NO_DEPT);
            }
        }
        for(int i = 0;i<userSkill.getUserCodeList().size();i++){
            userSkill.setCreatePersonCode(user.getUserCode());
            userSkill.setCreatePersonName(user.getUserName());
            userSkill.setCreateTime(new Date());
            userSkill.setIsDelete(0);
            userSkill.setUserCode(userSkill.getUserCodeList().get(i));
            userSkill.setUserSkillType(userSkill.getUserSkillTypeList().toString());
            this.save(userSkill);
        }
        return true;
    }

    @Override
    public Boolean updateUserSkill(UserSkill userSkill) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        // 判断是否有该人才
        List<UserSkill> list = new ArrayList<>();
        if (userSkill.getUserType() != 5) {
            /*List<UserSkill> list = this.list(new QueryWrapper<UserSkill>()
                    .eq("USER_CODE", userSkill.getUserCode())
                    .eq("USER_TYPE", userSkill.getUserType())
                    .eq("USER_SKILL_TYPE", userSkill.getUserSkillType())
                    .ne("ID", userSkill.getId())
                    .eq("IS_DELETE", 0)
            );*/
            list = getUserSkillTypeList(userSkill);
            if (list.size() < 0) {
                return false;
            }
        }
        userSkill.setUpdatePersonCode(user.getUserCode());
        userSkill.setUpdatePersonName(user.getUserName());
        userSkill.setUpdateTime(new Date());
        if(userSkill.getUserSkillTypeList() != null && userSkill.getUserSkillTypeList().size() > 0){
            userSkill.setUserSkillType(userSkill.getUserSkillTypeList().toString());
        }
        this.updateById(userSkill);
        return true;
    }

    @Override
    public void deleteUserSkill(UserSkill userSkill) {
        UserCacheData user = ThreadUserContext.getCurrentCacheUser();
        this.update(new UpdateWrapper<UserSkill>()
                .eq("ID", userSkill.getId())
                .set("UPDATE_PERSON_CODE", user.getUserCode())
                .set("UPDATE_PERSON_NAME", user.getUserName())
                .set("UPDATE_TIME", new Date())
                .set("IS_DELETE", 1)
        );
    }

    @Override
    public SkillTypeListVo skillTypeList(UserSkillPo userSkillPo) {
        SkillTypeListVo skillTypeListVo = new SkillTypeListVo();
        List<UserSkillType> userSkillTypes = userSkillTypeService.list();
        int aaa = 0;
        if (CollUtil.isNotEmpty(userSkillTypes)) {
            List<UserSkillType> userSkillTypeList = this.getBaseMapper().userInfo(userSkillPo);
            if (CollUtil.isNotEmpty(userSkillTypeList)) {
                Map<String, List<UserSkillType>> map = userSkillTypeList.stream().collect(Collectors.groupingBy(UserSkillType::getUserSkillType));
                for (UserSkillType userSkillType : userSkillTypes) {
                    if (map.containsKey(userSkillType.getUserSkillType())) {
                        List<UserSkillType> skillTypes = map.get(userSkillType.getUserSkillType());
                        userSkillType.setSum(skillTypes.size());
                        aaa = aaa + skillTypes.size();
                    }

                }
            }
        }
        skillTypeListVo.setUserSkillTypes(userSkillTypes);
        skillTypeListVo.setSum(aaa);
        return skillTypeListVo;
    }

    @Override
    public TechnologyVo technology(UserSkillPo userSkillPo) {
        TechnologyVo technologyVo = new TechnologyVo();
        Integer sum = this.getBaseMapper().technology(userSkillPo);
        technologyVo.setSum(sum);
        UserSkillPo skillPo = new UserSkillPo();
        skillPo.setDeptCode(userSkillPo.getDeptCode());
        skillPo.setType(1);
        Integer typeOne = this.getBaseMapper().technology(skillPo);
        technologyVo.setTypeOne(typeOne);
        UserSkillPo po = new UserSkillPo();
        po.setDeptCode(userSkillPo.getDeptCode());
        po.setType(2);
        Integer typeTwo = this.getBaseMapper().technology(po);
        technologyVo.setTypeTwo(typeTwo);
        return technologyVo;
    }

    @Override
    public HeightAndWeightVo heightAndWeight(UserSkillPo userSkillPo) {
        HeightAndWeightVo heightAndWeightVo = new HeightAndWeightVo();
        List<UserInfoVo> userInfoVos = this.getBaseMapper().heightAndWeight(userSkillPo);
        List<HeightVo> mans = new ArrayList<>();
        List<HeightVo> girls = new ArrayList<>();
        if (CollUtil.isNotEmpty(userInfoVos)) {
            Map<Integer, List<UserInfoVo>> map = userInfoVos.stream().collect(Collectors.groupingBy(UserInfoVo::getSex));
            List<UserInfoVo> infoVos = map.get(1);
            if (CollUtil.isNotEmpty(infoVos)) {
                for (UserInfoVo infoVo : infoVos) {
                    HeightVo heightVo = new HeightVo();
                    heightVo.setHeight(infoVo.getHeight());
                    heightVo.setWeight(infoVo.getWeight());
                    mans.add(heightVo);
                }
            }

            List<UserInfoVo> infoVoList = map.get(2);
            if (CollUtil.isNotEmpty(infoVoList)) {
                for (UserInfoVo infoVo : infoVoList) {
                    HeightVo heightVo = new HeightVo();
                    heightVo.setHeight(infoVo.getHeight());
                    heightVo.setWeight(infoVo.getWeight());
                    girls.add(heightVo);
                }
            }
        }
        WeightVo weightVo = new WeightVo();
        weightVo.setHeightVos(mans);
        heightAndWeightVo.setMan(weightVo);
        WeightVo weightVo1 = new WeightVo();
        weightVo1.setHeightVos(girls);
        heightAndWeightVo.setGirl(weightVo1);
        return heightAndWeightVo;
    }

    @Override
    public SkillVo skill(UserSkillPo userSkillPo) {
        SkillVo skillVo = new SkillVo();
        List<SkillInfo> skillInfos = this.getBaseMapper().SkillInfo();
        List<String> list = this.getBaseMapper().skillCount(userSkillPo);
        if (CollUtil.isNotEmpty(list)) {
            skillVo.setSum(list.size());
            Map<String, List<String>> map = list.stream().collect(Collectors.groupingBy(item -> item));
            for (SkillInfo skillInfo : skillInfos) {
                if (map.containsKey(skillInfo.getCode())) {
                    skillInfo.setCount(map.get(skillInfo.getCode()).size());
                }
            }
        }

        skillVo.setSkillInfos(skillInfos);
        return skillVo;
    }

    @Override
    public SkillVo commandCount(UserSkillPo userSkillPo) {
        SkillVo skillVo = new SkillVo();
        List<SkillInfo> skillInfos = this.getBaseMapper().commandCount();
        List<String> list = this.getBaseMapper().list(userSkillPo);
        if (CollUtil.isNotEmpty(list)) {
            skillVo.setSum(list.size());
            Map<String, List<String>> map = list.stream().collect(Collectors.groupingBy(item -> item));
            for (SkillInfo skillInfo : skillInfos) {
                if (map.containsKey(skillInfo.getCode())) {
                    skillInfo.setCount(map.get(skillInfo.getCode()).size());
                }
            }
        }

        skillVo.setSkillInfos(skillInfos);

        return skillVo;
    }

    @Override
    public UserCountVo userCount() {
        UserCountVo userCountVo = new UserCountVo();
        Integer count = this.getBaseMapper().UserCountVo();
        userCountVo.setUserCount(count);
        userCountVo.setSkillCount(this.count(Wrappers.<UserSkill>lambdaQuery()
                .eq(UserSkill::getIsDelete, 0)
                .eq(UserSkill::getUserType, 1)));

        return userCountVo;
    }

    @Override
    public List<UserListVos> deptCodeByUserList(UserSkill userSkill) {
        List<UserListVos> userListVos = this.getBaseMapper().deptCodeByUserList(userSkill);
        return userListVos;
    }

    @Override
    public List<DeptCountVo> deptCount(UserSkillPo userSkillPo) {
        List<DeptCountVo> deptCountVos = this.getBaseMapper().deptList(userSkillPo);
        if (CollUtil.isNotEmpty(deptCountVos)) {
            deptCountVos= deptCountVos.stream().filter(i -> !i.getDeptName().equals("系统管理员-默认顶级部门")).collect(Collectors.toList());
            for (DeptCountVo deptCountVo : deptCountVos) {
                Integer count = this.getBaseMapper().deptCount(deptCountVo.getDeptCode());
                deptCountVo.setCount(count);
            }
            int sum = deptCountVos.stream().mapToInt(DeptCountVo::getCount).sum();
            for (DeptCountVo deptCountVo : deptCountVos) {
                deptCountVo.setPercentage(Integer.toString(sum));
            }
//            for (DeptCountVo deptCountVo : deptCountVos) {
//                if (deptCountVo.getCount()>0){
//                    BigDecimal divide = new BigDecimal(deptCountVo.getCount()).divide(new BigDecimal(sum), 2, BigDecimal.ROUND_HALF_UP);
//                    BigDecimal multiply = divide.multiply(new BigDecimal(100));
//                    deptCountVo.setPercentage(multiply +"%");
//                }else {
//                    deptCountVo.setPercentage("0%");
//                }
//            }
        }

        return deptCountVos;
    }

    @Override
    public AgeCountVo ageCount(UserSkillPo userSkillPo) {
        AgeCountVo ageCountVo = new AgeCountVo();
        for (int i = 0; i < 9; i++) {
            switch (i) {
                case 0:
                    userSkillPo.setAgeStart(18);
                    userSkillPo.setAgeEnd(23);
                    Integer aaa = this.getBaseMapper().ageCount(userSkillPo);
                    ageCountVo.setOne(aaa);
                    break;
                case 1:
                    userSkillPo.setAgeStart(24);
                    userSkillPo.setAgeEnd(29);
                    Integer bbb = this.getBaseMapper().ageCount(userSkillPo);
                    ageCountVo.setTwo(bbb);
                    break;
                case 2:
                    userSkillPo.setAgeStart(30);
                    userSkillPo.setAgeEnd(34);
                    Integer ccc = this.getBaseMapper().ageCount(userSkillPo);
                    ageCountVo.setThree(ccc);
                    break;
                case 3:
                    userSkillPo.setAgeStart(35);
                    userSkillPo.setAgeEnd(39);
                    Integer ddd = this.getBaseMapper().ageCount(userSkillPo);
                    ageCountVo.setFour(ddd);
                    break;
                case 4:
                    userSkillPo.setAgeStart(40);
                    userSkillPo.setAgeEnd(44);
                    Integer eee = this.getBaseMapper().ageCount(userSkillPo);
                    ageCountVo.setFive(eee);
                    break;
                case 5:
                    userSkillPo.setAgeStart(45);
                    userSkillPo.setAgeEnd(49);
                    Integer fff = this.getBaseMapper().ageCount(userSkillPo);
                    ageCountVo.setSix(fff);
                    break;
                case 6:
                    userSkillPo.setAgeStart(50);
                    userSkillPo.setAgeEnd(54);
                    Integer ggg = this.getBaseMapper().ageCount(userSkillPo);
                    ageCountVo.setSeven(ggg);
                    break;
                case 7:
                    userSkillPo.setAgeStart(55);
                    userSkillPo.setAgeEnd(64);
                    Integer hhh = this.getBaseMapper().ageCount(userSkillPo);
                    ageCountVo.setEight(hhh);
                    break;
                case 8:
                    userSkillPo.setAgeStart(65);
                    userSkillPo.setAgeEnd(1000);
                    Integer iii = this.getBaseMapper().ageCount(userSkillPo);
                    ageCountVo.setNine(iii);
                    break;
            }

        }
        return ageCountVo;
    }

    @Override
    public MarriageVo marriage(UserSkillPo userSkillPo) {
        MarriageVo marriageVo = new MarriageVo();
        int sum = 0;
        for (int i = 0; i < 4; i++) {
            userSkillPo.setMarriage(i + 1);
            switch (i) {
                case 0:
                    Integer aaa = this.getBaseMapper().marriage(userSkillPo);
                    marriageVo.setOne(aaa);
                    sum = sum + aaa;
                    break;
                case 1:

                    Integer bbb = this.getBaseMapper().marriage(userSkillPo);
                    marriageVo.setTwo(bbb);
                    sum = sum + bbb;
                    break;
                case 2:

                    Integer ccc = this.getBaseMapper().marriage(userSkillPo);
                    marriageVo.setThree(ccc);
                    sum = sum + ccc;
                    break;
                case 3:
                    Integer ddd = this.getBaseMapper().marriage(userSkillPo);
                    marriageVo.setFour(ddd);
                    sum = sum + ddd;
                    break;
            }
        }
        marriageVo.setSum(sum);
        return marriageVo;
    }

    @Override
    public EducationCountVo educationCount(UserSkillPo userSkillPo) {
        EducationCountVo educationCountVo = new EducationCountVo();
        List<SkillInfo> skillInfos = this.getBaseMapper().educationCount(userSkillPo);
        if (CollUtil.isNotEmpty(skillInfos)) {
            Map<Integer, List<SkillInfo>> map = skillInfos.stream().collect(Collectors.groupingBy(SkillInfo::getEducation));
            int sum = 0;
            int aaa = 0;
            if (map.containsKey(1)) {
                aaa = map.get(1).size();
            }
            if (map.containsKey(2)) {
                aaa = aaa + map.get(2).size();
            }
            sum = sum + aaa;
            educationCountVo.setOne(aaa);
            if (map.containsKey(3)) {
                sum = sum + map.get(3).size();
                educationCountVo.setTwo(map.get(3).size());
            }
            if (map.containsKey(4)) {
                sum = sum + map.get(4).size();
                educationCountVo.setThree(map.get(4).size());
            }
            if (map.containsKey(5)) {
                sum = sum + map.get(5).size();
                educationCountVo.setFour(map.get(5).size());
            }

            if (map.containsKey(6)) {
                sum = sum + map.get(6).size();
                educationCountVo.setFive(map.get(6).size());
            }
            if (map.containsKey(7)) {
                sum = sum + map.get(7).size();
                educationCountVo.setSix(map.get(7).size());
            }
            educationCountVo.setCount(sum);
        }
        return educationCountVo;
    }


}
